#include "bsp_sound.h"

#define SOUND_PORT I2C_NUM_0
#define I2C_SCL_PIN GPIO_NUM_1
#define I2C_SDA_PIN GPIO_NUM_0

#define I2S_MCK_PIN 3
#define I2S_BCK_PIN 2
#define I2S_DATA_WS_PIN 5
#define I2S_DATA_OUT_PIN 6
#define I2S_DATA_IN_PIN 4

#define PA_GPIO 7

static i2c_master_bus_handle_t i2c_bus_handle;
static i2s_chan_handle_t speakerHandle;
static i2s_chan_handle_t micHandle;

static esp_codec_dev_handle_t codec_dev;

// 音频驱动代码
void bsp_sound_Init()
{

    // I2C总线初始化 - 用于控制ES8311芯片
    bsp_sound_i2c_Init();
    // I2S接口初始化 - 用于音频数据传输
    bsp_sound_i2s_Init();
    // ES8311编解码器初始化 - 音频处理核心
    bsp_sound_es8311_Init();
}

// I2C总线初始化 - 用于控制ES8311芯片
void bsp_sound_i2c_Init()
{
    i2c_master_bus_config_t i2c_bus_config = {0};
    i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT;    // 使用默认时钟源
    i2c_bus_config.i2c_port = SOUND_PORT;               // I2C端口0
    i2c_bus_config.scl_io_num = I2C_SCL_PIN;            // SCL引脚1
    i2c_bus_config.sda_io_num = I2C_SDA_PIN;            // SDA引脚0
    i2c_bus_config.glitch_ignore_cnt = 7;               // 信号滤波，抗干扰
    i2c_bus_config.flags.enable_internal_pullup = true; // 启用内部上拉电阻(没有硬件上拉电阻)
    i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle);
}
// I2S接口初始化 - 用于音频数据传输
void bsp_sound_i2s_Init()
{
    i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
    i2s_std_config_t std_cfg = {
        .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000),                            // 16kHz采样率
        .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(16, I2S_SLOT_MODE_MONO), // 16位，单声道
        .gpio_cfg = {
            .mclk = I2S_MCK_PIN,      // 主时钟
            .bclk = I2S_BCK_PIN,      // 位时钟
            .ws = I2S_DATA_WS_PIN,    // 字选择
            .dout = I2S_DATA_OUT_PIN, // 数据输出
            .din = I2S_DATA_IN_PIN    // 数据输入
        },
    };
     // 创建输入和输出通道
    i2s_new_channel(&chan_cfg, &speakerHandle, &micHandle);

    // 初始化输出和输入通道
    i2s_channel_init_std_mode(speakerHandle, &std_cfg);
    i2s_channel_init_std_mode(micHandle, &std_cfg);

    // 使能通道
    i2s_channel_enable(speakerHandle);
    i2s_channel_enable(micHandle);
}
// ES8311编解码器初始化 - 音频处理核心
void bsp_sound_es8311_Init()
{
    // 配置数据接口（I2S）
    audio_codec_i2s_cfg_t i2s_cfg = {
        .rx_handle = micHandle,    // 接收句柄（麦克风）
        .tx_handle = speakerHandle // 发送句柄（扬声器）
    };
    const audio_codec_data_if_t *data_if = audio_codec_new_i2s_data(&i2s_cfg);
    
    // 配置控制接口（I2C）
    audio_codec_i2c_cfg_t i2c_cfg = {
        .port = SOUND_PORT,
        .addr = ES8311_CODEC_DEFAULT_ADDR, // ES8311默认地址0x08
        .bus_handle = i2c_bus_handle};
    const audio_codec_ctrl_if_t *out_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);

    // ES8311特定配置
    es8311_codec_cfg_t es8311_cfg = {
        .codec_mode = ESP_CODEC_DEV_WORK_MODE_BOTH, // 同时支持播放和录音
        .ctrl_if = out_ctrl_if,
        .gpio_if = audio_codec_new_gpio(),
        .pa_pin = PA_GPIO, // 功放使能引脚
        .use_mclk = true   // 使用主时钟
    };
    // 创建编解码器实例
    const audio_codec_if_t *out_codec_if = es8311_codec_new(&es8311_cfg);

    // 创建设备配置
    esp_codec_dev_cfg_t dev_cfg = {
        .codec_if = out_codec_if,
        .data_if = data_if,
        .dev_type = ESP_CODEC_DEV_TYPE_IN_OUT // 输入输出设备
    };

    codec_dev = esp_codec_dev_new(&dev_cfg);

    // 设置音频参数
    esp_codec_dev_set_in_gain(codec_dev, 20.0); // 麦克风增益20dB
    esp_codec_dev_set_out_vol(codec_dev, 60.0); // 扬声器音量60%
}


/**
 * @brief 打开音频设备
 */
void bsp_sound_open(void)
{
    // 采样信息
    esp_codec_dev_sample_info_t fs = {
        .sample_rate     = 16000,   // 采样率
        .channel         = 1,       // 通道数
        .bits_per_sample = 16,      // 采样位数(采样深度)
    };

    if(codec_dev)
    {
        // 打开设备
        esp_codec_dev_open(codec_dev, &fs);
    }
}

/**
 * @brief 关闭音频设备
 *
 */
void bsp_sound_close(void)
{
    if(codec_dev)
    {
        esp_codec_dev_close(codec_dev);
    }
}


/**
 * @brief 播放
 *
 * @param data
 * @param size
 */
int bsp_sound_write(uint8_t *data, int size)
{
    if(codec_dev && data && size > 0)
    {
        
        return esp_codec_dev_write(codec_dev, (void *)data, size);
    }

    return ESP_CODEC_DEV_WRITE_FAIL;
}

/**
 * @brief 读取麦克风的数据 录音
 *
 * @param data 存放数据的缓存
 * @param size 读取的数据的长度
 */
int bsp_sound_read(uint8_t data[], int size)
{
    if(codec_dev && data && size > 0)
    {
        
        // 阻塞式读取
        return esp_codec_dev_read(codec_dev, data, size);
    }

    return ESP_CODEC_DEV_READ_FAIL;
}

int  svol = 60;
void setVolume(int volume)
{
    if(codec_dev)
    {
        svol = volume;
        esp_codec_dev_set_out_vol(codec_dev, volume);
    }
}

void setMute(bool mute)
{
    if(codec_dev && mute)
    {
        esp_codec_dev_set_out_vol(codec_dev, 0);
    }
    else if(codec_dev && mute == false)
    {
        esp_codec_dev_set_out_vol(codec_dev, svol);
    }
}

